// ************************************************
// ****************** SIGNATURE *******************
// ************************************************

// **** TYPES ****

type Class1: ...;
type Class2: ...;
type Prop1: ...;
type Prop2: ...;

// *** PREDICATES ***

// the two two hidden predicates
predicate cmap: Class1 x Class2;
predicate pmap: Prop1 x Prop2;
// and two non hidden filter predicates on the hidden predicates restricting their domain
predicate ccandidate: Class1 x Class2;
predicate pcandidate: Prop1 x Prop2;
// concepts hierarchy
predicate subsumes1: Class1 x Class1;
predicate subsumes2: Class2 x Class2;
// disjointness between concepts
predicate disjoint1: Class1 x Class1;
predicate disjoint2: Class2 x Class2;
// property domains in the concept hierarchy
predicate domainsub1: Prop1 x Class1;
predicate domainsub2: Prop2 x Class2;
predicate domainsup1: Prop1 x Class1;
predicate domainsup2: Prop2 x Class2;
// disjointness between property domains and concept
predicate domaindis1: Prop1 x Class1;
predicate domaindis2: Prop2 x Class2;
// property range in the concept hierarchy
predicate rangesub1: Prop1 x Class1;
predicate rangesub2: Prop2 x Class2;
predicate rangesup1: Prop1 x Class1;
predicate rangesup2: Prop2 x Class2;
// disjointness between property range and concept
predicate rangedis1: Prop1 x Class1;
predicate rangedis2: Prop2 x Class2;

predicate cmap_confidence: Class1 x Class2 x Double;
predicate pmap_confidence: Prop1 x Prop2 x Double;

predicate class1: Class1;
predicate class2: Class2;
predicate prop1: Prop1;
predicate prop2: Prop2;

// *** HIDDEN vs. OBSERVED ***

hidden: cmap, pmap;
observed: class1, class2, prop1, prop2, ccandidate, pcandidate, subsumes1, subsumes2, disjoint1, disjoint2, domainsub1, domainsub2, domainsup1, domainsup2, domaindis1, domaindis2, rangesub1, rangesub2, rangesup1, rangesup2, rangedis1, rangedis2, cmap_confidence, pmap_confidence;

// *** WEIGHTS ***

weight w_c_stab: Double-;
weight w_pc_sub_domain_stab: Double-;
weight w_pc_sub_range_stab: Double-;

// ********************************************************************
// *********************** FORMULAE ***********************************
// ********************************************************************

// ***** STATE OF THE ART *****


//a-priori confidence weights for concept correspondences
factor: for Class1 c1, Class2 c2, Double cconf
	if class1(c1) & class2(c2) & cmap_confidence(c1, c2, cconf)
        add [cmap(c1, c2)] * cconf;
		
//a-priori confidence weights for property correspondences
factor: for Prop1 p1, Prop2 p2, Double pconf
	if prop1(p1) & prop2(p2) & pmap_confidence(p1, p2, pconf)
        add [pmap(p1, p2)] * pconf;	


// make alignment one-to-one and functional for concept correspondences
factor: for Class1 c1
	if class1(c1): 
	|Class2 c2: cmap(c1,c2)| <= 1;

factor: for Class2 c2
	if class2(c2): 
	|Class1 c1: cmap(c1,c2)| <= 1;
	
// make alignment one-to-one and functional for property correspondences
factor: for Prop1 p1
	if prop1(p1): 
	|Prop2 p2: pmap(p1,p2)| <= 1;

factor: for Prop2 p2
	if prop2(p2): 
	|Prop1 p1: pmap(p1,p2)| <= 1;		

// ***** COHERENCE-CONSTRAINTS (hard) *****

// constraints between concept correspondences

factor: for Class1 a1, Class1 b1, Class2 a2, Class2 b2
	   if subsumes1(a1, b1) & disjoint2(a2, b2) & ccandidate(a1, a2) & ccandidate(b1, b2):
	   cmap(a1, a2) => !cmap(b1, b2);

factor: for Class1 a1, Class1 b1, Class2 a2, Class2 b2
	   if subsumes2(a2, b2) & disjoint1(a1, b1) & ccandidate(a1, a2) & ccandidate(b1, b2):
	   cmap(a1, a2) => !cmap(b1, b2);

// constraints between concept and property correspondences via domains

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	   if domainsub1(a1, b1) & domaindis2(a2, b2) & pcandidate(a1, a2) & ccandidate(b1, b2):
	   pmap(a1, a2) => !cmap(b1, b2);

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	   if domainsup1(a1, b1) & domaindis2(a2, b2) & pcandidate(a1, a2) & ccandidate(b1, b2):
	   pmap(a1, a2) => !cmap(b1, b2);

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	   if domainsub2(a2, b2) & domaindis1(a1, b1) & pcandidate(a1, a2) & ccandidate(b1, b2):
	   pmap(a1, a2) => !cmap(b1, b2);

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	   if domainsup2(a2, b2) & domaindis1(a1, b1) & pcandidate(a1, a2) & ccandidate(b1, b2):
	   pmap(a1, a2) => !cmap(b1, b2);
	   
// constraints between concept and property correspondences via ranges  
	
factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	   if rangesub1(a1, b1) & rangedis2(a2, b2) & pcandidate(a1, a2) & ccandidate(b1, b2):
	   pmap(a1, a2) => !cmap(b1, b2);

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	   if rangesup1(a1, b1) & rangedis2(a2, b2) & pcandidate(a1, a2) & ccandidate(b1, b2):
	   pmap(a1, a2) => !cmap(b1, b2);

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	   if rangesub2(a2, b2) & rangedis1(a1, b1) & pcandidate(a1, a2) & ccandidate(b1, b2):
	   pmap(a1, a2) => !cmap(b1, b2);

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	   if rangesup2(a2, b2) & rangedis1(a1, b1) & pcandidate(a1, a2) & ccandidate(b1, b2):
	   pmap(a1, a2) => !cmap(b1, b2);

	         
// constraints between property correspondences still missing are (not sure wether they are important
// ... 4 constraints for domain sub vs domain dis
// ... 4 constraints for range sub vs range dis 
	
// ****** STABILITY-CONSTRAINTS (soft) ******

// constraints between concept correspondences
	   
factor: for Class1 a1, Class1 b1, Class2 a2, Class2 b2
	if subsumes1(a1, b1) & !subsumes2(a2, b2) & ccandidate(a1,a2) & ccandidate(b1,b2)
		add [cmap(a1, a2) & cmap(b1, b2)] * w_c_stab;
		
factor: for Class1 a1, Class1 b1, Class2 a2, Class2 b2
	if !subsumes1(a1, b1) & subsumes2(a2, b2) & ccandidate(a1,a2) & ccandidate(b1,b2)
		add [cmap(a1, a2) & cmap(b1, b2)] * w_c_stab;		
	
// constraints between property and concept correspondences	via domain	

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	if domainsub1(a1, b1) & !domainsub2(a2, b2) & pcandidate(a1, a2) & ccandidate(b1, b2)
	   add [pmap(a1, a2) & cmap(b1, b2)] * w_pc_sub_domain_stab;
	   
factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	if !domainsub1(a1, b1) & domainsub2(a2, b2) & pcandidate(a1, a2) & ccandidate(b1, b2)
	   add [pmap(a1, a2) & cmap(b1, b2)] * w_pc_sub_domain_stab;
		
// constraints between property and concept correspondences	via range

factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	if !rangesub1(a1, b1) & rangesub2(a2, b2) & pcandidate(a1, a2) & ccandidate(b1, b2)
	   add [pmap(a1, a2) & cmap(b1, b2)] * w_pc_sub_range_stab;
	   
factor: for Prop1 a1, Class1 b1, Prop2 a2, Class2 b2
	if rangesub1(a1, b1) & !rangesub2(a2, b2) & pcandidate(a1, a2) & ccandidate(b1, b2)
	   add [pmap(a1, a2) & cmap(b1, b2)] * w_pc_sub_range_stab;	   


		



